package cmms;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;

import controller.FileIOController;
import controller.MemberController;
import controller.ProgramFlowControl;
import controller.RecordController;
import controller.VenueController;
import dataStructure.LinkedList;

import entity.BookingRecord;
import entity.FileAsso;
import entity.Member;
import entity.RedemptionRecord;
import entity.Staff;
import entity.Venue;

//Club Member Management system

public class CMMS extends ProgramFlowControl {
	private Staff staff;
	
	// For storing different data including members, venues, record.
	private LinkedList<Member> members;
	private LinkedList<Venue> venues;
	private LinkedList<BookingRecord> bookingRecords;
	private LinkedList<RedemptionRecord> redemptionRecords;
	
	// Controller class;
	private FileIOController fileIOControl; // For input data from file
	private MemberController memberControl; // Member Controller, all operations about will be executed here.
	private VenueController venueControl;	// Booking, checking information about different venues.
	private RecordController recordControl; // Record Controller, for processing records.

	public CMMS(Staff staff) throws IOException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, ParseException, InvocationTargetException, NoSuchMethodException {
		// Constructor, executed once ProgramManager is running.
		super("Club Member Management System");
		
		this.staff=staff;
		this.initialAttr();
	}

	private void initialAttr() throws IOException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, ParseException, InvocationTargetException, NoSuchMethodException { // Just initializing attrs.
		members = new LinkedList<Member>();
		venues = new LinkedList<Venue>();
		bookingRecords = new LinkedList<BookingRecord>();
		redemptionRecords = new LinkedList<RedemptionRecord>();
		
		fileIOControl = new FileIOController();

		fileIOControl.getFileAssoList().addContent(new FileAsso("member", "member.txt"));
		fileIOControl.getFileAssoList().addContent(new FileAsso("venue", "venue.txt"));
		fileIOControl.getFileAssoList().addContent(new FileAsso("bookingRecord", "bookingRecord.txt"));
		fileIOControl.getFileAssoList().addContent(new FileAsso("redemptionRecord", "redemptionRecord.txt"));

		// call FileIOController to get data from varies txt files defined in fileIOControl constructor.
		if (this.prepareData()) {
			this.begins();
		} else {
			System.out.println("During capturing data from txt to Program Memory,\n errors found. Please contact technicans for checking.\nCMMS stops running now.");
		}
	}

	private boolean prepareData() throws IOException, ParseException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NullPointerException {
		// passing list for FileIOController to input data from identifier 'member' defined in fileIOControl constructor.
		if (fileIOControl.inputData(this.members, "member"))
			if (fileIOControl.inputData(this.venues, "venue"))
				if (fileIOControl.inputData(this.bookingRecords, "bookingRecord"))
					if (fileIOControl.inputData(this.redemptionRecords, "redemptionRecord"))
						return true;
		return false;
	}

	private void begins() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, IOException, InvocationTargetException, NoSuchMethodException, ParseException {
		// All data are well prepared, CMMS can be used now.
		memberControl = new MemberController(this.members, this.redemptionRecords, this.staff);
		recordControl = new RecordController(this.bookingRecords, this.redemptionRecords, this.staff);
		venueControl = new VenueController(this.venues, this.members, this.bookingRecords, this.staff);

		this.addNewChoice("1", "1. Members Management", this.memberControl, "begin");
		this.addNewChoice("2", "2. Venues Management", this.venueControl, "begin");
		this.addNewChoice("3", "3. Record Checking", this.recordControl, "begin");
		this.setTeminateOption("x", "Press x to exit CMMS", this, "updateFileData"); // clearUpMemory

		this.flowControl();
	}

	public boolean updateFileData() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, InterruptedException, NoSuchFieldException, IOException, ParseException {
		// User decided to exit CMMS, CMMS start preparing data in memory and input it to txt file according to scheme defined in fileIOController before.
		if (fileIOControl.outputDataToFile(this.members, "member"))
			if (fileIOControl.outputDataToFile(this.venues, "venue"))
				if (fileIOControl.outputDataToFile(this.bookingRecords, "bookingRecord"))
					if (fileIOControl.outputDataToFile(this.redemptionRecords, "redemptionRecord")) {
						System.out.println("Files are updated correspondingly. CMMS exiting, Thanks you using CMMS provided by Do Inc. ");
						return true;
					}
		return false;
	}

}
